package Demo16;


import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

//模拟实现生产者消费者模型
class MyBlockingQueue {
    private String[] arr = null;

    //数组起始下标
    private int head = 0;

    //数组结束下标
    private int end = 0;

    //记录有效元素个数
    private int size = 0;

    //锁对象
    private Object locker = new Object();

    //构造数组大小
    public MyBlockingQueue(int num) {
        arr = new String[num];
    }

    //线程放置元素
    public void put(String elem) throws InterruptedException {
        synchronized (locker) {
            //如果队列满了
            while (size >= arr.length) {
                locker.wait();
            }
            arr[end] = elem;
            end++;
            //判断 end 是否到了末尾
            if(end >= arr.length) {
                end = 0;
            }
            //有效元素加一
            size++;
            //唤醒 take 的阻塞
            locker.notify();
        }
    }

    //线程取走元素
    public String take() throws InterruptedException {
        synchronized (locker) {
            //如果队列为空
            while (size <= 0) {
                locker.wait();
            }

            //得到队列最前面的元素
            String ret = arr[head];
            head++;
            //判断 head 是否到了末尾
            if(head >= arr.length) {
                head = 0;
            }
            //有效元素减一
            size--;
            //唤醒 put 的阻塞
            locker.notify();
            //返回队列最前面的元素
            return ret;

        }
    }
}


//使用
public class Demo16 {

    public static void main(String[] args) throws InterruptedException {

        BlockingQueue<String> queue = new LinkedBlockingQueue<>(100);

        //生产者线程
        Thread producer = new Thread(() -> {
            int count = 0;
            try {
                while (true) {
                    queue.put("" + count);
                    System.out.println("生产了一个元素: " + count);
                    count++;
                    //设置生产速度
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        //消费者线程
        Thread consumer = new Thread(() -> {
            try {
                while (true) {
                    String elem = queue.take();
                    System.out.println("消费了一个元素: " + elem);
                    //设置消费速度
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        producer.start();
        consumer.start();
        producer.join();
        consumer.join();
    }
}
